import { ref, onMounted } from "vue";

export const useImageVerify = (width = 120, height = 40) => {
  const domRef = ref(null);
  const imgCode = ref("");

  function setImgCode(code) {
    imgCode.value = code;
  }

  function getImgCode() {
    if (!domRef.value) return;
    imgCode.value = draw(domRef.value, width, height);
  }

  onMounted(() => {
    getImgCode();
  });

  return {
    domRef,
    imgCode,
    setImgCode,
    getImgCode,
  };
};
/*  该函数通过在Canvas上绘制随机字符、线条和噪点生成一个验证码图像，
 并返回生成的验证码字符串。这种方法常用于网页的注册或登录表单，以防止自动化的恶意行为。 */
function draw(dom, width, height) {
  let imgCode = "";

  const NUMBER_STRING = "0123456789";

  const ctx = dom.getContext("2d"); //获取Canvas的2D绘图上下文。
  if (!ctx) return imgCode;

  ctx.fillStyle = randomColor(180, 230);
  ctx.fillRect(0, 0, width, height);

  for (let i = 0; i < 4; i += 1) {
    //循环四次，每次生成一个随机数字字符，并将其添加到imgCode中。
    const text = NUMBER_STRING[randomNum(0, NUMBER_STRING.length)];
    imgCode += text;
    //设置字符的字体大小和旋转角度
    const fontSize = randomNum(18, 41);
    const deg = randomNum(-30, 30);

    ctx.font = `${fontSize}px Simhei`;
    ctx.textBaseline = "top";
    ctx.fillStyle = randomColor(80, 150);
    //使用ctx.save()和ctx.restore()保存和恢复Canvas状态，以便在每次绘制字符时应用不同的变换。
    ctx.save();
    //使用ctx.translate()和ctx.rotate()设置字符的位置和旋转角度。
    ctx.translate(30 * i + 15, 15);
    ctx.rotate((deg * Math.PI) / 180);
    // 使用ctx.fillText()绘制字符。
    ctx.fillText(text, -15 + 5, -15);
    ctx.restore();
  }

  for (let i = 0; i < 5; i += 1) {
    //循环五次，每次绘制一条随机位置和颜色的线条。
    ctx.beginPath();
    ctx.moveTo(randomNum(0, width), randomNum(0, height));
    ctx.lineTo(randomNum(0, width), randomNum(0, height));
    ctx.strokeStyle = randomColor(180, 230);
    ctx.closePath();
    ctx.stroke();
  }

  for (let i = 0; i < 41; i += 1) {
    // 循环41次，每次在随机位置绘制一个小圆点。
    ctx.beginPath();
    ctx.arc(randomNum(0, width), randomNum(0, height), 1, 0, 2 * Math.PI);
    ctx.closePath();
    ctx.fillStyle = randomColor(150, 200);
    ctx.fill();
  }

  return imgCode;
}

function randomColor(min, max) {
  const r = randomNum(min, max);
  const g = randomNum(min, max);
  const b = randomNum(min, max);
  return `rgb(${r},${g},${b})`;
}

function randomNum(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}
